﻿using Sgr.Application.ViewModels;
using System.Linq.Expressions;

namespace Sgr.Application.Queries
{
    /// <summary>
    /// 只支持IQueryable查询的读库上下文接口
    /// </summary>
    public interface IModuleQueryContext : IDisposable, IAsyncDisposable
    {
        #region 查询构建

        /// <summary>
        /// 获取指定实体的查询对象
        /// </summary>
        /// <typeparam name="T">实体类型</typeparam>
        /// <returns>查询对象</returns>
        IQueryable<T> Query<T>() where T : class;

        /// <summary>
        /// 使用导航属性获取查询对象
        /// </summary>
        /// <typeparam name="T">实体类型</typeparam>
        /// <param name="navigationPropertyPath">导航属性路径</param>
        /// <returns>查询对象</returns>
        IQueryable<T> QueryWithNavigation<T>(params string[] navigationPropertyPath) where T : class;

        #endregion 查询构建

        #region 基础查询

        /// <summary>
        /// 异步获取第一个或默认的实体
        /// </summary>
        Task<T?> FirstOrDefaultAsync<T>(
            IQueryable<T> query,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 异步获取唯一或默认的实体
        /// </summary>
        Task<T?> SingleOrDefaultAsync<T>(
            IQueryable<T> query,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 异步获取列表
        /// </summary>
        Task<IEnumerable<T>> ToListAsync<T>(
            IQueryable<T> query,
            CancellationToken cancellationToken = default);

        #endregion 基础查询

        #region 高级查询

        /// <summary>
        /// 分页查询
        /// </summary>
        Task<PagedResponse<T>> PaginateAsync<T>(
            IQueryable<T> query,
            int skip,
            int take,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 分页查询
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="query"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        Task<PagedResponse<T>> PagedListByPageSizeAsync<T>(
            IQueryable<T> query,
             int pageIndex,
             int pageSize,
            CancellationToken cancellationToken = default);

        #endregion 高级查询

        #region 聚合查询

        /// <summary>
        /// 异步获取总数
        /// </summary>
        Task<int> CountAsync<T>(
            IQueryable<T> query,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 异步获取长整型总数
        /// </summary>
        Task<long> LongCountAsync<T>(
            IQueryable<T> query,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 异步判断是否存在满足条件的记录
        /// </summary>
        Task<bool> AnyAsync<T>(
            IQueryable<T> query,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 异步获取最大值
        /// </summary>
        Task<TResult?> MaxAsync<T, TResult>(
            IQueryable<T> query,
            Expression<Func<T, TResult?>> selector,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 异步获取最小值
        /// </summary>
        Task<TResult?> MinAsync<T, TResult>(
            IQueryable<T> query,
            Expression<Func<T, TResult?>> selector,
            CancellationToken cancellationToken = default);

        /// <summary>
        /// 异步获取平均值
        /// </summary>
        Task<decimal?> AverageAsync<T>(
            IQueryable<T> query,
            Expression<Func<T, decimal?>> selector,
            CancellationToken cancellationToken = default);

        #endregion 聚合查询
    }
}